/**
 * FeeyoDataSource.java
 * Jan 9, 2010
 */
package com.dlplay.flightinfo.source;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.htmlparser.jericho.Element;
import net.htmlparser.jericho.HTMLElementName;
import net.htmlparser.jericho.Source;

import com.dlplay.flightinfo.core.CityMap;
import com.dlplay.flightinfo.data.AirFlightCode;
import com.dlplay.flightinfo.data.AirlineCode;
import com.dlplay.flightinfo.data.Airport;
import com.dlplay.flightinfo.data.AirportTerminalCode;
import com.dlplay.flightinfo.data.CityCode;
import com.dlplay.flightinfo.data.FlightStatusMap;
import com.dlplay.flightinfo.data.RTFlightStatus;
import com.dlplay.flightinfo.data.RealTimeFlightInfo;
import com.dlplay.flightinfo.data.Weather;
import com.dlplay.flightinfo.source.map.AirlineMap;
import com.google.appengine.repackaged.com.google.common.primitives.Bytes;

/**
 *
 * @author zhang yu
 *
 */
public class FeeyoDataSource extends DataSource 
	implements RealTimeFlightDS,AirportDataSource {
	
	private static final Logger log = Logger.getLogger(FeeyoDataSource.class.getName());
	private static final String FEEYO_FLIGNT_INFO = "http://wap.feeyo.com/flightstatus/searchnum.asp?flightNum=";
	private static final String FEEYO_WEATHER_INFO = "http://wap.feeyo.com/weather/show.asp?airport=";
	
	private static final String jp_rsscc_com ="http://jp.rsscc.com/dt_result.jsp?flyNo=";
	
	
	//DataSource priority 0~9 low to high
	public static final int DEFAULT_DATASOURCE_PRI = 9;

	/* (non-Javadoc)
	 * @see com.dlplay.flightinfo.core.AirportDataSource
	 */
	@Override
	public Airport getAirport(AirportTerminalCode code) {
		// TODO Auto-generated method stub

		Airport airport = new Airport();
		airport.setIdentifier(code);
		airport.setWeather(new Weather());
		String temp;

		//Try to get the airport information
		try {
			log.log(Level.INFO,"in processSubmit code " + code);
						
			//OK, now we need to perform the url fetch
			URL url = new URL(FEEYO_WEATHER_INFO + getName(code));
			log.log(Level.INFO,"in processSubmit URL url = ", url);
			
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            
            //we need to set the http header property
//            connection.setDoOutput(true);
//            connection.setDoInput(true);
//            connection.setRequestProperty("Content-Type", "text/xml;charset=utf-8");
            connection.setRequestProperty("use_intranet", "true");
            connection.setRequestMethod("GET");
            //set connection timeout to maximum 10
            connection.setConnectTimeout(95000); 
            connection.connect();
            
            //TODO Do we need to get length
            int length = connection.getContentLength();
            log.log(Level.INFO,"processSubmit: length " + length);
            
            //connection.getContent();
            //using html parser to parse the html
            log.log(Level.INFO,"in processSubmit Source source=new Source");
            Source source=new Source(new InputStreamReader(connection.getInputStream(), "utf-8"));
            Element ol = source.getFirstElement(HTMLElementName.OL);
//          <ol> 
//            <li class="first">所在位置：<a href="http://wap.feeyo.com/weather/">机场天气</a> >> 北京机场天气</li> 
//            
//            <li>发布时间：2010-1-9 17:00:00</li> 
//            <li>天气情况：<img src="http://www.feeyo.com/img/weather/sun.gif" style="width:25px;height:25px" align="absmiddle"> 晴天</li> 
//            <li>温　　度：-4℃</li> 
//            <li>能 见 度：很好</li> 
//            <li>专业报码：METAR ZBAA 090900Z 36002MPS 310V040 CAVOK M04/M15 Q1030 NOSIG=</li> 
//            
//            <li> 
//              <form action="http://wap.feeyo.com/weather/show.asp" method="post" name="sform" class="search"> 
//               城市名：<input type="text" name="airport" value="北京" size="10" /> 
//                <input type="hidden" name="airport4" value=""> 
//                <input name="submit" type="submit" value="搜索"/> 
//              </form> 
//            </li> 
//          </ol>
            
            if (ol != null)
            {
            	List<Element> elements = ol.getAllElements(HTMLElementName.LI);
            	//elements.remove(0);
            	//所在位置：
            	
            	//Get 发布时间：2010-1-9 17:00:00
            	temp = elements.get(1).getTextExtractor().toString();
            	String tempDate = temp.substring(temp.indexOf("：") + 1);
            	if (tempDate.charAt(0) >= '0' && temp.charAt(0)<= '9')
	        	{
	            	//tempDate 2010-1-9 17:00:00
	            	airport.getWeather().setPubTime(new Date());
	            	airport.getWeather().getPubTime().setYear(new Integer(tempDate.substring(0, 4)));
	            	airport.getWeather().getPubTime().setMonth(new Integer(tempDate.substring(5, 6)));
	            	airport.getWeather().getPubTime().setDate(new Integer(tempDate.substring(7, 8)));
	            	
	            	tempDate = tempDate.substring(tempDate.indexOf(":") - 2);
	            	//tempDate = 17:00:00
	            	airport.getWeather().getPubTime().setHours(new Integer(tempDate.substring(0, 2)));
	            	airport.getWeather().getPubTime().setMinutes(new Integer(tempDate.substring(3, 5)));
	            	airport.getWeather().getPubTime().setSeconds(new Integer(tempDate.substring(6, 7)));
	        	}
            	
            	//Get 天气情况：
            	temp = elements.get(2).getTextExtractor().toString();
            	//temp = 天气情况： 晴天
            	String tempWeather = temp.substring(temp.indexOf("：") + 1);
            	airport.getWeather().setWeather(tempWeather);
            	
            	//Get 温　　度：-4℃
            	temp = elements.get(3).getTextExtractor().toString();
            	String tempTemperature = temp.substring(temp.indexOf("：") + 1);
            	airport.getWeather().setTemperatureNow(new Integer(tempTemperature.substring(0, tempTemperature.indexOf("℃")).trim()));
            	
            	//Get 能 见 度：很好
            	temp = elements.get(4).getTextExtractor().toString();
            	String tempVisibility = temp.substring(temp.indexOf("：") + 1);
            	airport.getWeather().setVisibility(tempVisibility);
            	
            	//Get 专业报码：METAR ZBAA 090900Z 36002MPS 310V040 CAVOK M04/M15 Q1030 NOSIG=
            	temp = elements.get(5).getTextExtractor().toString();
            	String tempCode = temp.substring(temp.indexOf("：") + 1);
            	airport.getWeather().setProCode(tempCode);
            	
            	//Get Airport name changed to UTF-8
            	Element input = source.getFirstElement(HTMLElementName.INPUT);
            	airport.setIdentifier(getName(input.getAttributeValue("value")));            	
                
            	//TODO 24-hours forcast
            	
            	//OK, now we need to reture the info
            	return airport;
            	
            }

		}catch (MalformedURLException e) {
            // ...
        	e.printStackTrace();
        	log.log(Level.WARNING,"in processSubmit MalformedURLException");
			return null;
        	
        } catch (IOException e) {
            // ...
        	e.printStackTrace();
        	log.log(Level.WARNING,"in processSubmit IOException");
			return null;
        } catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			log.log(Level.WARNING,e.getMessage());
		}
		return null;
	}

	private static final String getName(AirportTerminalCode code) {
		// TODO real change
		return "北京";
	}

	private static final AirportTerminalCode getName(String attributeValue) {
		//TODO real change
		return AirportTerminalCode.PEK_T3;
	}

	/* (non-Javadoc)
	 * @see com.dlplay.flightinfo.core.FlightDataSource#getFlightByNum()
	 */
	@Override
	public RealTimeFlightInfo getFlightByNum(AirFlightCode flightNum) {
		// TODO Auto-generated method stub
		
		//First, we prepare for the Data
		RealTimeFlightInfo targetInfo = new RealTimeFlightInfo(flightNum);
		Date tmpDate = new Date();
		
		try {
			log.log(Level.INFO,"in processSubmit flightNum " + flightNum);						
			//OK, now we need to perform the url fetch

			URL url = new URL(FEEYO_FLIGNT_INFO + flightNum);
			log.log(Level.INFO,"in processSubmit URL url = " + url);
			
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            
            //we need to set the http header property
//            connection.setDoOutput(true);
//            connection.setDoInput(true);
//            connection.setRequestProperty("Content-Type", "text/xml;charset=utf-8");
//            connection.setRequestProperty("use_intranet", "true");
            connection.setRequestMethod("GET");
            //set connection timeout to maximum 10
            connection.setConnectTimeout(95000); 
            connection.connect();
            
            //TODO Do we need to get length
            int length = connection.getContentLength();
            log.log(Level.INFO,"processSubmit: length " + length);
            
            //connection.getContent();
            //using html parser to parse the html
            log.log(Level.INFO,"in processSubmit Source source=new Source");
            Source source=new Source(new InputStreamReader(connection.getInputStream(), "utf-8"));
//            Element titleElement=source.getFirstElement(HTMLElementName.TITLE);
            List<Element> le = source.getAllElements(HTMLElementName.LI);
            //Here we analysis the fetch result of http://wap.feeyo.com/flightstatus/searchnum.asp?flightNum=
//            <ol> <li class="first"><h1>航班号MU5105实时航班动态：</h1></li>    
//            <li><h1>航班号:MU5105</h1></li><li><h1>出发地:上海虹桥</h1></li><li><h1>目的地:北京</h1></li><li>预计起飞时间:10:00<br>预计到达时间:12:01</li><li>实际起飞时间:10:15<br>实际到达时间:12:02</li><li>接机楼:T2</li><li>状态:<span class='hbzt'>到达</span></li><li style='border-top:1px solid #CCEEFF'></li>  
//             <li> 航段查询</li> 
            if (le.size() > 1)
            {
            	
	            String temp = le.get(1).getTextExtractor().toString();
	        	if (temp.contains("很抱歉"))
	        	{
	        		//很抱歉！未收集您需要的航班！
	        		log.log(Level.WARNING,"in processSubmit flightNum null");
	        		return null;
	        	}
	        	
	        	//Get the related infomation
	        	
//	        	0航班号MU5105实时航班动态：
//	        	1航班号:MU5105
//	        	2出发地:上海虹桥
//	        	3目的地:北京
//	        	4预计起飞时间:10:00 预计到达时间:12:01
//	        	6实际起飞时间:10:15 实际到达时间:12:02
//	        	接机楼:T2
//	        	状态:到达
	        	
	        	//Get the flight Number
	        	targetInfo.setKey(temp.substring(temp.indexOf(":") + 1));
	        		//we also use the flightNumber as the infoId
//	        	targetInfo.setId(targetInfo.getNumber());
	        	
	        	//setFromCity
	        	temp = le.get(2).getTextExtractor().toString();
	        	targetInfo.setFrom(getCity(temp.substring(temp.indexOf(":")+ 1)));
	        	//setToCity
	        	temp = le.get(3).getTextExtractor().toString();
	        	targetInfo.setTo(getCity(temp.substring(temp.indexOf(":")+ 1)));
	        	
	        	//setPlanDepartureTime
	        	temp = le.get(4).getTextExtractor().toString();
	        	temp = temp.substring(temp.indexOf(":")+ 1);
	        	//temp = 10:00 预计到达时间:12:01
	        	
	        	//we have no date info, just the hours and minutes
	        	
	        	tmpDate.setHours(new Integer(temp.substring(0, temp.indexOf(":"))).intValue());
	        	tmpDate.setMinutes(new Integer(temp.substring(temp.indexOf(":")+ 1, temp.indexOf(":") + 3)).intValue());
	        	targetInfo.setPlanDeparture(tmpDate);
	        	
	        	temp = temp.substring(temp.indexOf(":") + 1);
	        	//temp = 00 预计到达时间:12:01
	        	temp = temp.substring(temp.indexOf(":") + 1);
	        	//temp = 12:01
	        	//we have no date info, just the hours and minutes
	        	tmpDate = new Date();
	        	tmpDate.setHours(new Integer(temp.substring(0, temp.indexOf(":"))).intValue());
	        	tmpDate.setMinutes(new Integer(temp.substring(temp.indexOf(":")+ 1)).intValue());
	        	targetInfo.setPlanArrival(tmpDate);
	        	
	        	//setActualDepartureTime
	        	temp = le.get(5).getTextExtractor().toString();
	        	temp = temp.substring(temp.indexOf(":")+ 1);
	        	
//	        	if (temp.matches("[0-2][0-9]:[0-2][0-9]*"))
	        	if (temp.charAt(0) >= '0' && temp.charAt(0)<= '9')
	        	{
		        	//we have no date info, just the hours and minutes
	        		tmpDate = new Date();
		        	tmpDate.setHours(new Integer(temp.substring(0, temp.indexOf(":"))).intValue());
		        	tmpDate.setMinutes(new Integer(temp.substring(temp.indexOf(":")+ 1, temp.indexOf(":")+ 3)).intValue());
		        	targetInfo.setActualDeparture(tmpDate);
	        	}
	        	
	        	//setActualArrivalTime
	        	temp = temp.substring(temp.indexOf(":") + 1);
	        	//temp = 00 实际到达时间:12:01
	        	temp = temp.substring(temp.indexOf(":") + 1);
	        	//temp = 12:01
	        	if (temp.length() > 4)
	        	{
	        		tmpDate = new Date();
		        	//we have no date info, just the hours and minutes
		        	tmpDate.setHours(new Integer(temp.substring(0, temp.indexOf(":"))));
		        	tmpDate.setMinutes(new Integer(temp.substring(temp.indexOf(":")+ 1)));
		        	targetInfo.setActualArrival(tmpDate);
	        	}
	        	
	        	
	        	//setReception
	        	temp = le.get(6).getTextExtractor().toString();
	        	temp = temp.substring(temp.indexOf(":")+ 1);
	        	targetInfo.setReception(temp);
	        	
	        	//setStatus
	        	temp = le.get(7).getTextExtractor().toString();
	        	temp = temp.substring(temp.indexOf(":")+ 1);
	        	targetInfo.setStatus(getStatuc(temp));
	        	
	        	//OK we've get a possible new flight number info
	        	
	        	//Right now we still need two more info
	        	//air company and accurate info, which could get from http://jp.rsscc.com/
	        	log.log(Level.INFO,"in processSubmit URL url2 = new URL");
	        	URL url2 = new URL(jp_rsscc_com + targetInfo.getKey());
	            HttpURLConnection connection2 = (HttpURLConnection) url2.openConnection();
	            connection2.setRequestMethod("GET");

	            //set connection timeout to maximum 10
	            connection2.setConnectTimeout(95000); 
	            connection2.connect();
	            int length2 = connection2.getContentLength();
	            log.log(Level.INFO,"processSubmit: length2 " + length2);
	            
	            //connection.getContent();
	            //using html parser to parse the html
	            log.log(Level.INFO,"in processSubmit Source source2");
	            Source source2=new Source(new InputStreamReader(connection2.getInputStream(), "utf-8"));
	            List<Element> trs = source2.getAllElements(HTMLElementName.TR);
//	            displaySegments(trs);
	            //Here we analysis the fetch result of http://wap.feeyo.com/flightstatus/searchnum.asp?flightNum=
//	            <ol> <li class="first"><h1>航班号MU5105实时航班动态：</h1></li>    
//	            <li><h1>航班号:MU5105</h1></li><li><h1>出发地:上海虹桥</h1></li><li><h1>目的地:北京</h1></li><li>预计起飞时间:10:00<br>预计到达时间:12:01</li><li>实际起飞时间:10:15<br>实际到达时间:12:02</li><li>接机楼:T2</li><li>状态:<span class='hbzt'>到达</span></li><li style='border-top:1px solid #CCEEFF'></li>  
//	             <li> 航段查询</li> 
	            if (trs.size() < 10)
	            {
	            	//no valid entry
	        		log.log(Level.WARNING,"No valid entry");
	        		return null;
	            }
	            else 
	            {
	            	//set the air company
	            	temp = trs.get(4).getTextExtractor().toString();
	            	temp = temp.substring(temp.indexOf(":")+ 1);
	            	targetInfo.setAirCompany(getAirline(temp));
		        	
		        	//set the air company
	            	temp = trs.get(13).getTextExtractor().toString();

	            	int i = temp.indexOf("%");
	            	if (i > -1)
	            	{
		            	temp = temp.substring(i-2, i);
		            	targetInfo.setAccuracy(new Float(temp));
	            	}
	            	
	            }
	            targetInfo.setLatestUpdate(new Date());	            
	            return targetInfo;
	
            }

        } catch (MalformedURLException e) {
            // ...
        	e.printStackTrace();
        	log.log(Level.WARNING,"in processSubmit MalformedURLException");
			return null;
        	
        } catch (IOException e) {
            // ...
        	e.printStackTrace();
        	log.log(Level.WARNING,"in processSubmit IOException");
			return null;
        } catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			log.log(Level.WARNING,e.getMessage());
		}
		return null;
	}

	private static final AirlineCode getAirline(String temp) {
		return AirlineMap.getCode(temp);		
	}

	private static final RTFlightStatus getStatuc(String temp) {
		System.out.println("status "+temp);
		return FlightStatusMap.getStatus(temp);
	}

	private static final CityCode getCity(String str) {
		// TODO real change
		System.out.println("Terminal "+str);
		return CityMap.getCode(str) ;
	}

}
